library(tidyverse)

load the data from prev. lesson

surveys_complete <- read_csv("/Users/rossum/Dropbox/teaching/Workshops/SCW-DCW/lessonsDC/R-ecology-lesson/data_output/surveys_complete.csv")

Challenge - scatter plot

Use what you just learned to create a scatter plot of weight over genus with the field plot types showing in different colors. Is this a good way to show this type of data?

ggplot(data = surveys_complete, mapping = aes(x = genus, y = weight)) +
   geom_point(aes(color = plot_type))

Bonus challenge - overplotting

With a geom_point() plot, we couldn’t tell if 1 or 1000 points were drawn at the same location. When points overlap, this is called “overplotting” and it can hide information in a plot. We can avoid this several ways. Try recreating the weight vs hindfoot_length scatter plot with the following changes

Which of these communicated the distribution of the data most clearly? What are their strengths and weaknesses?

Bonus bonus: google: “Rpackage hexbin” and see if you can install it and use it for an alternative plot

ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length)) +
    geom_bin2d()

ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length)) +
    geom_point()+geom_density2d()

ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length)) +
    geom_point(alpha = 0.1)

#install.packages("hexbin")
library(hexbin)
ggplot(data = surveys_complete, mapping = aes(x = weight, y = hindfoot_length)) +
 geom_hex()

Challenge: violoin plot

Boxplots are useful summaries, but they hide the shape of the distribution. For example, if the distribution is bimodal, we would not see it in a boxplot. An alternative to the boxplot is the violin plot, where the shape (of the density of points) is drawn.

In many types of data, it is important to consider the scale of the observations. For example, it may be worth changing the scale of the axis to better distribute the observations in the space of the plot. Changing the scale of the axes is done similarly to adding/modifying other components (i.e., by incrementally adding commands). Try making these modifications:

So far, we’ve looked at the distribution of weight within genera. Try making a new plot to explore the distribution of another variable within each genus.

Bonus challenge: box plot alternatives

check out https://www.r-graph-gallery.com/all-graphs/ Is there another libary that you could download and use to make some nice plots?


Challenge: line plot - median weight by month

Does the median weight per genus change over the year? e.g. are there some months when animals tend to be heavier? For simplicity, consider the median weight across all years.


medianWeightByGenusByMonth <- surveys_complete %>%
  group_by(genus, month) %>% 
  summarise(medianWeight = median(weight,na.rm = T))

ggplot(data = medianWeightByGenusByMonth, 
       mapping = aes(x = month, y = medianWeight, color = genus)) +
    geom_line()

Bonus challenge: variability in trend

Is the trend that we saw in the previous plot consistent for most years sampled?


medianWeightByGenusByMonthByYear <- surveys_complete %>%
  group_by(year, genus, month) %>% 
  summarise(medianWeight = median(weight,na.rm = T))

ggplot(data = medianWeightByGenusByMonthByYear, 
       mapping = aes(x = month, y = medianWeight, 
                     group = interaction(year,genus),color=genus)) +
  geom_line()

# Can you find a better way to visualise an answer?

Challenge - sex diff by species?

How does the abundance of each species change through the years for females and males. (Use the variable species_id)


countsByYearBySexBySpecies <- surveys_complete %>%
  group_by(year, species_id, sex) %>% 
  summarise(n = n())

 ggplot(data = countsByYearBySexBySpecies, mapping = aes(x = year, y = n, color = sex)) +
     geom_line() +
     facet_wrap(.~ species_id)
 

Bonus challenge: investigate species “RF”

In the line plot above, species “RF” looks really weird. Take a closer look a the data for this species. Why does it look this way? You might want to try a “stacked bar chart” (see the section “Histogram on a categorical variable” on this site: http://r-statistics.co/Top50-Ggplot2-Visualizations-MasterList-R-Code.html)

surveys_complete %>% 
  filter(species_id %in% c("RF")) %>% 
  ggplot(aes(x=year,fill=sex))+geom_bar()

Challenge: weight by year

Use what you just learned to create a plot that depicts how the average weight of each genus changed through the years.

Answer

 yearly_weight <- surveys_complete %>%
                 group_by(year, genus) %>%
                  summarize(weightMean = mean(weight))
 ggplot(data = yearly_weight, mapping = aes(x=year, y=weightMean)) +
    geom_line() +
    facet_wrap(.~ genus) +
    theme_bw()

Challenge: free style

With all of this information in hand, please take another five minutes to either improve one of the plots generated in this exercise or create a beautiful graph of your own. Use the RStudio ggplot2 cheat sheet for inspiration. Here are some ideas:

sessionInfo()
LS0tCnRpdGxlOiAnRGF0YSB2aXN1YWxpemF0aW9uIHdpdGggZ2dwbG90MjogQ2hhbGxlbmdlcycKYXV0aG9yOiAiVGhlYSBWYW4gUm9zc3VtIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IGthYmxlCiAgICB0b2M6IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIGNvZGVfZm9sZGluZzogaGlkZQplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG89VFJVRSxldmFsPUYpCmBgYAoKYGBge3IgbG9hZC1wYWNrYWdlLCBtZXNzYWdlPUZBTFNFLCBwdXJsPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCgpsb2FkIHRoZSBkYXRhIGZyb20gcHJldi4gbGVzc29uCgpgYGB7ciBsb2FkLWRhdGEsIHB1cmw9RkFMU0V9CnN1cnZleXNfY29tcGxldGUgPC0gcmVhZF9jc3YoIi9Vc2Vycy9yb3NzdW0vRHJvcGJveC90ZWFjaGluZy9Xb3Jrc2hvcHMvU0NXLURDVy9sZXNzb25zREMvUi1lY29sb2d5LWxlc3Nvbi9kYXRhX291dHB1dC9zdXJ2ZXlzX2NvbXBsZXRlLmNzdiIpCmBgYAoKCgojIENoYWxsZW5nZSAtIHNjYXR0ZXIgcGxvdAoKVXNlIHdoYXQgeW91IGp1c3QgbGVhcm5lZCB0byBjcmVhdGUgYSBzY2F0dGVyIHBsb3Qgb2YgYHdlaWdodGAgb3ZlcgpgZ2VudXNgIHdpdGggdGhlIGZpZWxkIHBsb3QgdHlwZXMgc2hvd2luZyBpbiBkaWZmZXJlbnQgY29sb3JzLiBJcyB0aGlzIGEgZ29vZAp3YXkgdG8gc2hvdyB0aGlzIHR5cGUgb2YgZGF0YT8KCmBgYHtyIHNjYXR0ZXItY2hhbGxlbmdlLCBwdXJsPUZBTFNFfQpnZ3Bsb3QoZGF0YSA9IHN1cnZleXNfY29tcGxldGUsIG1hcHBpbmcgPSBhZXMoeCA9IGdlbnVzLCB5ID0gd2VpZ2h0KSkgKwogICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IHBsb3RfdHlwZSkpCmBgYAoKCiMgQm9udXMgY2hhbGxlbmdlIC0gb3ZlcnBsb3R0aW5nCgpXaXRoIGEgYGdlb21fcG9pbnQoKWAgcGxvdCwgd2UgY291bGRuJ3QgdGVsbCBpZiAxIG9yIDEwMDAgcG9pbnRzIHdlcmUgZHJhd24gYXQgdGhlIHNhbWUgbG9jYXRpb24uIFdoZW4gcG9pbnRzIG92ZXJsYXAsIHRoaXMgaXMgY2FsbGVkICJvdmVycGxvdHRpbmciIGFuZCBpdCBjYW4gaGlkZSBpbmZvcm1hdGlvbiBpbiBhIHBsb3QuIFdlIGNhbiBhdm9pZCB0aGlzIHNldmVyYWwgd2F5cy4gVHJ5IHJlY3JlYXRpbmcgdGhlIHdlaWdodCB2cyBoaW5kZm9vdF9sZW5ndGggc2NhdHRlciBwbG90IHdpdGggdGhlIGZvbGxvd2luZyBjaGFuZ2VzCgotIHRyeSByZXBsYWNpbmcgZ2VvbV9wb2ludCgpIHdpdGggZ2VvbV9iaW4yZCgpCi0gdHJ5IGFkZGluZyBnZW9tX2RlbnNpdHkyZCgpIG9uIHRvcCBvZiBnZW9tX3BvaW50KCkgCi0gdHJ5IHJlcGxhY2luZyBnZW9tX3BvaW50KCkgd2l0aCBnZW9tX3BvaW50KGFscGhhPTAuMikKCldoaWNoIG9mIHRoZXNlIGNvbW11bmljYXRlZCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBkYXRhIG1vc3QgY2xlYXJseT8gCldoYXQgYXJlIHRoZWlyIHN0cmVuZ3RocyBhbmQgd2Vha25lc3Nlcz8KCkJvbnVzIGJvbnVzOiBnb29nbGU6ICJScGFja2FnZSBoZXhiaW4iIGFuZCBzZWUgaWYgeW91IGNhbiBpbnN0YWxsIGl0IGFuZCB1c2UgaXQgZm9yIGFuIGFsdGVybmF0aXZlIHBsb3QKCmBgYHtyIG92ZXJwbG90dGluZy1zb2xufQpnZ3Bsb3QoZGF0YSA9IHN1cnZleXNfY29tcGxldGUsIG1hcHBpbmcgPSBhZXMoeCA9IHdlaWdodCwgeSA9IGhpbmRmb290X2xlbmd0aCkpICsKICAgIGdlb21fYmluMmQoKQoKZ2dwbG90KGRhdGEgPSBzdXJ2ZXlzX2NvbXBsZXRlLCBtYXBwaW5nID0gYWVzKHggPSB3ZWlnaHQsIHkgPSBoaW5kZm9vdF9sZW5ndGgpKSArCiAgICBnZW9tX3BvaW50KCkrZ2VvbV9kZW5zaXR5MmQoKQoKZ2dwbG90KGRhdGEgPSBzdXJ2ZXlzX2NvbXBsZXRlLCBtYXBwaW5nID0gYWVzKHggPSB3ZWlnaHQsIHkgPSBoaW5kZm9vdF9sZW5ndGgpKSArCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4xKQoKI2luc3RhbGwucGFja2FnZXMoImhleGJpbiIpCmxpYnJhcnkoaGV4YmluKQpnZ3Bsb3QoZGF0YSA9IHN1cnZleXNfY29tcGxldGUsIG1hcHBpbmcgPSBhZXMoeCA9IHdlaWdodCwgeSA9IGhpbmRmb290X2xlbmd0aCkpICsKIGdlb21faGV4KCkKCmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIENoYWxsZW5nZTogdmlvbG9pbiBwbG90CgpCb3hwbG90cyBhcmUgdXNlZnVsIHN1bW1hcmllcywgYnV0IHRoZXkgaGlkZSB0aGUgKnNoYXBlKiBvZiB0aGUgZGlzdHJpYnV0aW9uLiBGb3IKZXhhbXBsZSwgaWYgdGhlIGRpc3RyaWJ1dGlvbiBpcyBiaW1vZGFsLCB3ZSB3b3VsZCBub3Qgc2VlIGl0IGluIGEKYm94cGxvdC4gQW4gYWx0ZXJuYXRpdmUgdG8gdGhlIGJveHBsb3QgaXMgdGhlIHZpb2xpbiBwbG90LCB3aGVyZSB0aGUgc2hhcGUgCihvZiB0aGUgZGVuc2l0eSBvZiBwb2ludHMpIGlzIGRyYXduLgoKLSBSZXBsYWNlIHRoZSBib3ggcGxvdCB3aXRoIGEgdmlvbGluIHBsb3Q7IHNlZSBgZ2VvbV92aW9saW4oKWAuCgpJbiBtYW55IHR5cGVzIG9mIGRhdGEsIGl0IGlzIGltcG9ydGFudCB0byBjb25zaWRlciB0aGUgKnNjYWxlKiBvZiB0aGUKb2JzZXJ2YXRpb25zLiAgRm9yIGV4YW1wbGUsIGl0IG1heSBiZSB3b3J0aCBjaGFuZ2luZyB0aGUgc2NhbGUgb2YgdGhlIGF4aXMgdG8KYmV0dGVyIGRpc3RyaWJ1dGUgdGhlIG9ic2VydmF0aW9ucyBpbiB0aGUgc3BhY2Ugb2YgdGhlIHBsb3QuICBDaGFuZ2luZyB0aGUgc2NhbGUKb2YgdGhlIGF4ZXMgaXMgZG9uZSBzaW1pbGFybHkgdG8gYWRkaW5nL21vZGlmeWluZyBvdGhlciBjb21wb25lbnRzIChpLmUuLCBieQppbmNyZW1lbnRhbGx5IGFkZGluZyBjb21tYW5kcykuIFRyeSBtYWtpbmcgdGhlc2UgbW9kaWZpY2F0aW9uczoKCi0gUmVwcmVzZW50IHdlaWdodCBvbiB0aGUgbG9nfjEwfiBzY2FsZTsgc2VlIGBzY2FsZV95X2xvZzEwKClgLgoKU28gZmFyLCB3ZSd2ZSBsb29rZWQgYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiB3ZWlnaHQgd2l0aGluIGdlbmVyYS4gVHJ5IG1ha2luZyBhCm5ldyBwbG90IHRvIGV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBhbm90aGVyIHZhcmlhYmxlIHdpdGhpbiBlYWNoIGdlbnVzLgoKLSBDcmVhdGUgYSBib3hwbG90IGZvciBgaGluZGZvb3RfbGVuZ3RoYC4gT3ZlcmxheSB0aGUgYm94cGxvdCBsYXllciBvbiBhIGppdHRlcgogIGxheWVyIHRvIHNob3cgYWN0dWFsIG1lYXN1cmVtZW50cy4KCgpgYGB7ciBib3hwbG90LWNoYWxsZW5nZSwgZXZhbD1GQUxTRSwgcHVybD1UUlVFLCBlY2hvPUZBTFNFfQojIyBDaGFsbGVuZ2Ugd2l0aCBib3hwbG90czoKIyMgIFN0YXJ0IHdpdGggdGhlIGJveHBsb3Qgd2UgY3JlYXRlZDoKZ2dwbG90KGRhdGEgPSBzdXJ2ZXlzX2NvbXBsZXRlLCBtYXBwaW5nID0gYWVzKHggPSBnZW51cywgeSA9IHdlaWdodCkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjMpCgojIyAgMS4gUmVwbGFjZSB0aGUgYm94IHBsb3Qgd2l0aCBhIHZpb2xpbiBwbG90OyBzZWUgYGdlb21fdmlvbGluKClgLgoKZ2dwbG90KGRhdGEgPSBzdXJ2ZXlzX2NvbXBsZXRlLCBtYXBwaW5nID0gYWVzKHggPSBnZW51cywgeSA9IHdlaWdodCkpICsKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMykrCiAgZ2VvbV92aW9saW4oKQoKIyMgIDIuIFJlcHJlc2VudCB3ZWlnaHQgb24gdGhlIGxvZzEwIHNjYWxlOyBzZWUgYHNjYWxlX3lfbG9nMTAoKWAuCgpnZ3Bsb3QoZGF0YSA9IHN1cnZleXNfY29tcGxldGUsIG1hcHBpbmcgPSBhZXMoeCA9IGdlbnVzLCB5ID0gd2VpZ2h0KSkgKwogIGdlb21faml0dGVyKGFscGhhID0gMC4zKSsKICBnZW9tX3Zpb2xpbigpICsgCiAgc2NhbGVfeV9sb2cxMCgpCgojIyAgMy4gQ3JlYXRlIGJveHBsb3QgZm9yIGBoaW5kZm9vdF9sZW5ndGhgIG92ZXJsYWlkIG9uIGEgaml0dGVyIGxheWVyLgoKZ2dwbG90KGRhdGEgPSBzdXJ2ZXlzX2NvbXBsZXRlLCBtYXBwaW5nID0gYWVzKHggPSBnZW51cywgeSA9IGhpbmRmb290X2xlbmd0aCkpICsKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMykrCiAgZ2VvbV9ib3hwbG90KCkgCgpgYGAKCgojIEJvbnVzIGNoYWxsZW5nZTogYm94IHBsb3QgYWx0ZXJuYXRpdmVzCgpjaGVjayBvdXQgaHR0cHM6Ly93d3cuci1ncmFwaC1nYWxsZXJ5LmNvbS9hbGwtZ3JhcGhzLwpJcyB0aGVyZSBhbm90aGVyIGxpYmFyeSB0aGF0IHlvdSBjb3VsZCBkb3dubG9hZCBhbmQgdXNlIHRvIG1ha2Ugc29tZSBuaWNlIHBsb3RzPwoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIENoYWxsZW5nZTogbGluZSBwbG90IC0gbWVkaWFuIHdlaWdodCBieSBtb250aAoKRG9lcyB0aGUgbWVkaWFuIHdlaWdodCBwZXIgZ2VudXMgY2hhbmdlIG92ZXIgdGhlIHllYXI/IGUuZy4gYXJlIHRoZXJlIHNvbWUgbW9udGhzIHdoZW4gYW5pbWFscyB0ZW5kIHRvIGJlIGhlYXZpZXI/IEZvciBzaW1wbGljaXR5LCBjb25zaWRlciB0aGUgbWVkaWFuIHdlaWdodCBhY3Jvc3MgYWxsIHllYXJzLiAKCmBgYHtyIHRpbWUtc2VyaWVzLXdpdGgtY29sb3JzLCBwdXJsPUZBTFNFfQoKbWVkaWFuV2VpZ2h0QnlHZW51c0J5TW9udGggPC0gc3VydmV5c19jb21wbGV0ZSAlPiUKICBncm91cF9ieShnZW51cywgbW9udGgpICU+JSAKICBzdW1tYXJpc2UobWVkaWFuV2VpZ2h0ID0gbWVkaWFuKHdlaWdodCxuYS5ybSA9IFQpKQoKZ2dwbG90KGRhdGEgPSBtZWRpYW5XZWlnaHRCeUdlbnVzQnlNb250aCwgCiAgICAgICBtYXBwaW5nID0gYWVzKHggPSBtb250aCwgeSA9IG1lZGlhbldlaWdodCwgY29sb3IgPSBnZW51cykpICsKICAgIGdlb21fbGluZSgpCgpgYGAKCiMgQm9udXMgY2hhbGxlbmdlOiB2YXJpYWJpbGl0eSBpbiB0cmVuZAoKSXMgdGhlIHRyZW5kIHRoYXQgd2Ugc2F3IGluIHRoZSBwcmV2aW91cyBwbG90IGNvbnNpc3RlbnQgZm9yIG1vc3QgeWVhcnMgc2FtcGxlZD8gCgpgYGB7ciB0aW1lLXNlcmllcy13aXRoLWNvbG9ycy1tdWx0aWxpbmUsIHB1cmw9RkFMU0V9CgptZWRpYW5XZWlnaHRCeUdlbnVzQnlNb250aEJ5WWVhciA8LSBzdXJ2ZXlzX2NvbXBsZXRlICU+JQogIGdyb3VwX2J5KHllYXIsIGdlbnVzLCBtb250aCkgJT4lIAogIHN1bW1hcmlzZShtZWRpYW5XZWlnaHQgPSBtZWRpYW4od2VpZ2h0LG5hLnJtID0gVCkpCgpnZ3Bsb3QoZGF0YSA9IG1lZGlhbldlaWdodEJ5R2VudXNCeU1vbnRoQnlZZWFyLCAKICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9IG1vbnRoLCB5ID0gbWVkaWFuV2VpZ2h0LCAKICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSBpbnRlcmFjdGlvbih5ZWFyLGdlbnVzKSxjb2xvcj1nZW51cykpICsKICBnZW9tX2xpbmUoKQoKIyBDYW4geW91IGZpbmQgYSBiZXR0ZXIgd2F5IHRvIHZpc3VhbGlzZSBhbiBhbnN3ZXI/CgpgYGAKCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIENoYWxsZW5nZSAtIHNleCBkaWZmIGJ5IHNwZWNpZXM/CgpIb3cgZG9lcyB0aGUgYWJ1bmRhbmNlIG9mIGVhY2ggKnNwZWNpZXMqIGNoYW5nZSB0aHJvdWdoIHRoZSB5ZWFycyBmb3IgZmVtYWxlcyBhbmQgbWFsZXMuIChVc2UgdGhlIHZhcmlhYmxlIGBzcGVjaWVzX2lkYCkKCmBgYHtyfQoKY291bnRzQnlZZWFyQnlTZXhCeVNwZWNpZXMgPC0gc3VydmV5c19jb21wbGV0ZSAlPiUKICBncm91cF9ieSh5ZWFyLCBzcGVjaWVzX2lkLCBzZXgpICU+JSAKICBzdW1tYXJpc2UobiA9IG4oKSkKCiBnZ3Bsb3QoZGF0YSA9IGNvdW50c0J5WWVhckJ5U2V4QnlTcGVjaWVzLCBtYXBwaW5nID0gYWVzKHggPSB5ZWFyLCB5ID0gbiwgY29sb3IgPSBzZXgpKSArCiAgICAgZ2VvbV9saW5lKCkgKwogICAgIGZhY2V0X3dyYXAoLn4gc3BlY2llc19pZCkKIApgYGAKCiMgQm9udXMgY2hhbGxlbmdlOiBpbnZlc3RpZ2F0ZSBzcGVjaWVzICJSRiIKCkluIHRoZSBsaW5lIHBsb3QgYWJvdmUsIHNwZWNpZXMgIlJGIiBsb29rcyByZWFsbHkgd2VpcmQuIFRha2UgYSBjbG9zZXIgbG9vayBhIHRoZSBkYXRhIGZvciB0aGlzIHNwZWNpZXMuIFdoeSBkb2VzIGl0IGxvb2sgdGhpcyB3YXk/IApZb3UgbWlnaHQgd2FudCB0byB0cnkgYSAic3RhY2tlZCBiYXIgY2hhcnQiIChzZWUgdGhlIHNlY3Rpb24gIkhpc3RvZ3JhbSBvbiBhIGNhdGVnb3JpY2FsIHZhcmlhYmxlIiBvbiB0aGlzIHNpdGU6IGh0dHA6Ly9yLXN0YXRpc3RpY3MuY28vVG9wNTAtR2dwbG90Mi1WaXN1YWxpemF0aW9ucy1NYXN0ZXJMaXN0LVItQ29kZS5odG1sKQoKYGBge3J9CnN1cnZleXNfY29tcGxldGUgJT4lIAogIGZpbHRlcihzcGVjaWVzX2lkICVpbiUgYygiUkYiKSkgJT4lIAogIGdncGxvdChhZXMoeD15ZWFyLGZpbGw9c2V4KSkrZ2VvbV9iYXIoKQpgYGAKCgojIENoYWxsZW5nZTogd2VpZ2h0IGJ5IHllYXIgCgpVc2Ugd2hhdCB5b3UganVzdCBsZWFybmVkIHRvIGNyZWF0ZSBhIHBsb3QgdGhhdCBkZXBpY3RzIGhvdyB0aGUgYXZlcmFnZSB3ZWlnaHQKb2YgZWFjaCBnZW51cyBjaGFuZ2VkIHRocm91Z2ggdGhlIHllYXJzLgoKYGBge3IgYXZlcmFnZS13ZWlnaHQtdGltZS1zZXJpZXMsIGFuc3dlcj1UUlVFLCBwdXJsPUZBTFNFfQogeWVhcmx5X3dlaWdodCA8LSBzdXJ2ZXlzX2NvbXBsZXRlICU+JQogICAgICAgICAgICAgICAgIGdyb3VwX2J5KHllYXIsIGdlbnVzKSAlPiUKICAgICAgICAgICAgICAgICAgc3VtbWFyaXplKHdlaWdodE1lYW4gPSBtZWFuKHdlaWdodCkpCiBnZ3Bsb3QoZGF0YSA9IHllYXJseV93ZWlnaHQsIG1hcHBpbmcgPSBhZXMoeD15ZWFyLCB5PXdlaWdodE1lYW4pKSArCiAgICBnZW9tX2xpbmUoKSArCiAgICBmYWNldF93cmFwKC5+IGdlbnVzKSArCiAgICB0aGVtZV9idygpCmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgQ2hhbGxlbmdlOiBmcmVlIHN0eWxlCgpXaXRoIGFsbCBvZiB0aGlzIGluZm9ybWF0aW9uIGluIGhhbmQsIHBsZWFzZSB0YWtlIGFub3RoZXIgZml2ZSBtaW51dGVzIHRvCmVpdGhlciBpbXByb3ZlIG9uZSBvZiB0aGUgcGxvdHMgZ2VuZXJhdGVkIGluIHRoaXMgZXhlcmNpc2Ugb3IgY3JlYXRlIGEKYmVhdXRpZnVsIGdyYXBoIG9mIHlvdXIgb3duLiBVc2UgdGhlIFJTdHVkaW8gWyoqYGdncGxvdDJgKiogY2hlYXQgc2hlZXRdKGh0dHBzOi8vd3d3LnJzdHVkaW8uY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE2LzExL2dncGxvdDItY2hlYXRzaGVldC0yLjEucGRmKQpmb3IgaW5zcGlyYXRpb24uIEhlcmUgYXJlIHNvbWUgaWRlYXM6CgoqIFNlZSBpZiB5b3UgY2FuIGNoYW5nZSB0aGUgdGhpY2tuZXNzIG9mIHRoZSBsaW5lcy4KKiBDYW4geW91IGZpbmQgYSB3YXkgdG8gY2hhbmdlIHRoZSBuYW1lIG9mIHRoZSBsZWdlbmQ/IFdoYXQgYWJvdXQgaXRzIGxhYmVscz8KKiBUcnkgdXNpbmcgYSBkaWZmZXJlbnQgY29sb3IgcGFsZXR0ZSAoc2VlIGh0dHA6Ly93d3cuY29va2Jvb2stci5jb20vR3JhcGhzL0NvbG9yc18oZ2dwbG90MikvKS4KCgpgYGB7ciBzZXNzaW9uSW5mb30Kc2Vzc2lvbkluZm8oKQpgYGA=